package org.jdsm.flow.gxt.users.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.editor.client.Editor;
import com.google.web.bindery.autobean.shared.AutoBean;
import com.google.web.bindery.autobean.shared.AutoBeanFactory;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.data.shared.ModelKeyProvider;
import com.sencha.gxt.data.shared.PropertyAccess;
import com.sencha.gxt.data.shared.loader.JsonReader;
import com.sencha.gxt.data.shared.loader.PagingLoadConfig;
import com.sencha.gxt.data.shared.loader.PagingLoadResult;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: mikom
 * Date: 7/5/12
 * Time: 1:14 PM
 */

public interface UserAutoBeanFactory extends AutoBeanFactory {

    AutoBean<UserRecordResult> userResult();

    AutoBean<RoleRecordResult> roleResult();

    AutoBean<GroupRecordResult> groupResult();

    AutoBean<UserPagingLoadResult> userPagingLoadResult();

    AutoBean<RolePagingLoadResult> rolePagingLoadResult();

    AutoBean<GroupPagingLoadResult> groupPagingLoadResult();

    AutoBean<PagingListLoadConfig> pagingLoadConfig();

    AutoBean<Paging> paging();

    AutoBean<Response> responseResult();

    AutoBean<RoleResponse> roleResponseResult();

    AutoBean<GroupResponse> groupResponseResult();

    AutoBean<UserResponse> userResponseResult();

    public interface Paging {
        void setLimit(int limit);

        void setField(String field);

        void setOffset(int offset);

        void setSortOrder(String order);

        void setFilter(String filter);

        void setTotal(int total);

        int getLimit();

        String getField();

        int getOffset();

        String getSortOrder();

        String getFilter();

        int getTotal();
    }


    public interface User {
        Integer getId();

        String getName();

        String getNickName();

        String getHint();
    }

    public interface Role {
        Integer getId();

        String getName();

        Integer getPermission();

        void setName(String name);

        void setPermission(Integer permission);
    }

    public interface Group {
        Integer getId();

        String getName();

        void setName(String name);

        Integer getPermission();

        void setPermission(Integer permission);
    }

    public interface UserProperties extends PropertyAccess<User> {
        @Editor.Path("id")
        ModelKeyProvider<User> key();

        ValueProvider<User, String> name();

        ValueProvider<User, String> nickName();

        ValueProvider<User, String> hint();
    }

    public interface RoleProperties extends PropertyAccess<Role> {
        @Editor.Path("id")
        ModelKeyProvider<Role> key();

        ValueProvider<Role, String> name();

        ValueProvider<Role, Integer> permission();
    }

    public interface GroupProperties extends PropertyAccess<Group> {
        @Editor.Path("id")
        ModelKeyProvider<Group> key();

        ValueProvider<Group, String> name();

        ValueProvider<Group, Integer> permission();
    }

    public interface PagingListLoadConfig extends PagingLoadConfig {
        public void setPaging(Paging paging);

        public Paging getPaging();

        public void setUser(User user);
        public User getUser();

        public void setRole(Role role);
        public Role getRole();

        public void setGroup(Group group);
        public Group getGroup();
    }

    public interface Response {
        String getMessage();

        void setMessage(String message);

        Integer getCode();

        void setCode(Integer code);
    }

    public interface GroupResponse extends Response {
        Group getGroup();

        void setGroup(Group group);
        User getUser();

        void setUser(User user);

    }

    public interface RoleResponse extends Response {
        User getUser();

        void setUser(User user);

        Role getRole();

        void setRole(Role role);
    }

    public interface UserResponse extends Response {
        User getUser();

        void setUser(User user);

        Role getRole();

        void setRole(Role role);
    }

    public interface ResponseProperties extends PropertyAccess<Response> {
        @Editor.Path("code")
        ModelKeyProvider<Response> key();

        ValueProvider<Response, Integer> code();

        ValueProvider<Response, String> message();

    }

/*
    public interface EntryListRecordResult {
        Paging getPaging();
    }*/



    public interface UserRecordResult {
        List<User> getUsers();
        Paging getPaging();
    }

    public interface RoleRecordResult {
        List<Role> getRoles();
        Paging getPaging();
    }
    public interface GroupRecordResult{
        List<Group> getGroups();
        Paging getPaging();
    }

    public interface UserPagingLoadResult extends PagingLoadResult<User>{
        void setData(List<User> data);
    }
    public interface RolePagingLoadResult extends PagingLoadResult<Role>{
        void setData(List<Role> data);
    }

    public interface GroupPagingLoadResult extends PagingLoadResult<Group>{
        void setData(List<Group> data);
    }

    /*public interface EntryPagingLoadResult<T> extends PagingLoadResult<T> {
        void setData(List<T> data);
    }*/


    class ResponseDataRecordJsonReader extends JsonReader<List<Response>, Response> {

        public ResponseDataRecordJsonReader(AutoBeanFactory factory, Class<Response> rootBeanType) {
            super(factory, rootBeanType);
        }

        @Override
        protected List<Response> createReturnData(Object loadConfig, Response records) {
            List<Response> result = new ArrayList<Response>();
            result.add(records);
            return result;
        }
    }


    class UserDataRecordJsonReader extends JsonReader<UserPagingLoadResult, UserRecordResult> {

        public UserDataRecordJsonReader(AutoBeanFactory factory){
            this(factory, UserRecordResult.class);
        }

        public UserDataRecordJsonReader(AutoBeanFactory factory, Class<UserRecordResult> rootBeanType) {
            super(factory, rootBeanType);
        }

        @Override
        protected UserPagingLoadResult createReturnData(Object loadConfig, UserRecordResult records) {

            PagingLoadConfig config = (PagingLoadConfig) loadConfig;
            //todo this initialize factory to static construction
            UserAutoBeanFactory factory = GWT.create(UserAutoBeanFactory.class);
            UserPagingLoadResult result =  factory.create(UserPagingLoadResult.class).as();
            result.setData(records.getUsers());
            result.setOffset(config.getOffset());
            if (records.getPaging() != null) {
                result.setTotalLength(records.getPaging().getTotal());
                result.setOffset(records.getPaging().getOffset());
            }
            return result;//super.createReturnData(loadConfig, records);
        }
    }

    class RoleDataRecordJsonReader extends JsonReader<RolePagingLoadResult, RoleRecordResult> {

        public RoleDataRecordJsonReader(AutoBeanFactory factory){
            this(factory, RoleRecordResult.class);
        }

        public RoleDataRecordJsonReader(AutoBeanFactory factory, Class<RoleRecordResult> rootBeanType) {
            super(factory, rootBeanType);
        }

        @Override
        protected RolePagingLoadResult createReturnData(Object loadConfig, RoleRecordResult records) {

            PagingLoadConfig config = (PagingLoadConfig) loadConfig;
            //todo this initialize factory to static construction
            UserAutoBeanFactory factory = GWT.create(UserAutoBeanFactory.class);
            RolePagingLoadResult result =  factory.create(RolePagingLoadResult.class).as();
            result.setData(records.getRoles());
            result.setOffset(config.getOffset());
            if (records.getPaging() != null) {
                result.setTotalLength(records.getPaging().getTotal());
                result.setOffset(records.getPaging().getOffset());
            }
            return result;//super.createReturnData(loadConfig, records);
        }
    }


    class GroupDataRecordJsonReader extends JsonReader<GroupPagingLoadResult, GroupRecordResult> {

        public GroupDataRecordJsonReader(AutoBeanFactory factory){
            this(factory, GroupRecordResult.class);
        }

        public GroupDataRecordJsonReader(AutoBeanFactory factory, Class<GroupRecordResult> rootBeanType) {
            super(factory, rootBeanType);
        }

        @Override
        protected GroupPagingLoadResult createReturnData(Object loadConfig, GroupRecordResult records) {

            PagingLoadConfig config = (PagingLoadConfig) loadConfig;
            //todo this initialize factory to static construction
            UserAutoBeanFactory factory = GWT.create(UserAutoBeanFactory.class);
            GroupPagingLoadResult result =  factory.create(GroupPagingLoadResult.class).as();
            result.setData(records.getGroups());
            result.setOffset(config.getOffset());
            if (records.getPaging() != null) {
                result.setTotalLength(records.getPaging().getTotal());
                result.setOffset(records.getPaging().getOffset());
            }
            return result;//super.createReturnData(loadConfig, records);
        }
    }


}


